/*
 * Copyright (C) 2011 Nicola Bonzanni
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package nl.vu.few.ibivu.jlemon.concepts;


public interface HasEdges<N extends Node & Comparable<N>, E extends Edge & Comparable<E>, A extends Arc & Comparable<A> & HasEdge<E>> {
	
	/**
	 * Edges don't have source and target nodes, however, methods u() and v() are used to query the two end-nodes of an edge. The orientation of an edge that arises this way is called the inherent direction, it is used to define the default direction for the corresponding arcs.
	 * @param edge
	 * @return the first node of the given edge
	 * @see #v(Edge)
	 * @see #direction(Arc)
	 */
	N u(E edge);
	/**
	 * Edges don't have source and target nodes, however, methods u() and v() are used to query the two end-nodes of an edge. The orientation of an edge that arises this way is called the inherent direction, it is used to define the default direction for the corresponding arcs.
	 * @param edge
	 * @return the second node of the given edge
	 * @see #u(Edge)
	 * @see #direction(Arc)
	 */
	N v(E edge);
	/**
	 * 
	 * @param edge
	 * @return the ID of the given edge or -1 if the edge doesn't belong to this graph
	 */
	int id(E edge);

	/**
	 * 
	 * @param id
	 *            the edge ID
	 * @return the edge with the given ID or null if the ID is not a valid edge
	 *         ID for this graph
	 */
	E edgeFromId(int id);
	/**
	 * 
	 * @return an upper bound on the edge IDs
	 */
	int maxEdgeId();
	/**
	 * 
	 * @return the total number of edges in the graph
	 */
	int edgeNum();
	/**
	 * 
	 * @param arc
	 * @return {@code true} if the direction of the given arc is the same as the inherent orientation of the represented edge
	 */
	boolean direction(A arc);
	/**
	 * Direct the given edge.
	 * @param edge the edge used to build the arc
	 * @param inherent if {@code true}, then the direction of the returned arc is the same as the inherent orientation of the edge
	 * @return 
	 */
	A direct(E edge, boolean inherent);
	/**
	 * Direct the given edge.
	 * @param edge the edge used to build the arc
	 * @param node the source node of the arc
	 * @return the directed arc
	 */
	A direct(E edge, N node);
	/**
	 * Returns the oppositely directed arc representing the same edge.
	 * @param arc
	 * @return the oppositely directed arc representing the same edge
	 */
	A oppositeArc(A arc);
	/**
	 * Returns the node opposite to the given {@code node} on the given edge.
	 * @param node
	 * @param edge
	 * @return the node opposite to the given {@code node} on the given edge
	 */
	N oppositeNode(N node, E edge);
	/**
	 * TODO
	 * @return
	 */
	E firstEdge();
	/**
	 * TODO
	 * @param edge
	 * @return
	 */
	E next(E edge);
	/**
	 * TODO
	 * @param iterator
	 * @param node
	 * @return
	 */
	E firstInc(IncidentEdgeIterator<E> iterator, N node);
	/**
	 * TODO
	 * @param iterator
	 * @return
	 */
	E nextInc(IncidentEdgeIterator<E> iterator);
	/**
	 * Returns the Class type of the edge used in this graph instance
	 * @return the Class type of the edge used in this graph instance
	 */
	Class<E> getEdgeClass();
}
